home *** CD-ROM | disk | FTP | other *** search
/ Scene 96 / Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso / misc / coding / midas060 / src / asmrfile.asm next >
Encoding:
Assembly Source File  |  1997-01-16  |  19.5 KB  |  682 lines

  1. ;*      ASMRFILE.ASM
  2. ;*
  3. ;* Raw file I/O for MIDAS Sound System 16-bit C, Pascal or Assembler version
  4. ;*
  5. ;* $Id: asmrfile.asm,v 1.2 1997/01/16 18:41:59 pekangas Exp $
  6. ;*
  7. ;* Copyright 1996,1997 Housemarque Inc.
  8. ;*
  9. ;* This file is part of the MIDAS Sound System, and may only be
  10. ;* used, modified and distributed under the terms of the MIDAS
  11. ;* Sound System license, LICENSE.TXT. By continuing to use,
  12. ;* modify or distribute this file you indicate that you have
  13. ;* read the license and understand and accept it fully.
  14. ;*
  15.  
  16.  
  17. IDEAL
  18. P386
  19. JUMPS
  20.  
  21. INCLUDE "lang.inc"
  22. INCLUDE "errors.inc"
  23. INCLUDE "rawfile.inc"
  24. INCLUDE "mmem.inc"
  25.  
  26.  
  27.  
  28. DATASEG
  29.  
  30. D_long  fpos                            ; temporary file position used by
  31.                                         ; some functions
  32.  
  33.  
  34. IDATASEG
  35.  
  36.  
  37. ;/***************************************************************************\
  38. ;*      errorCodes
  39. ;*      ----------
  40. ;* Table of error codes, with one word (16-bit) DOS error code, followed by
  41. ;* the corresponding MIDAS error code.
  42. ;\***************************************************************************/
  43.  
  44. LABEL   errorCodes      WORD
  45.         DW      02h, errFileNotFound    ; File not found
  46.         DW      03h, errFileNotFound    ; Path not found
  47.         DW      04h, errTooManyFiles    ; Too many open files
  48.         DW      05h, errAccessDenied    ; Access denied
  49.         DW      06h, errInvalidFileHandle       ; Invalid handle
  50.         DW      07h, errHeapCorrupted   ; Memory control blocks destroyed
  51.         DW      08h, errOutOfMemory     ; Insufficient memory
  52.         DW      09h, errInvalidBlock    ; Invalid memory block address
  53.         DW      0Fh, errFileNotFound    ; Invalid drive specified
  54.         DW      13h, errAccessDenied    ; Attempt to write on a write-prot.
  55.         DW      14h, errFileNotFound    ; Unknown unit
  56.         DW      1Dh, errFileWrite       ; Write fault
  57.         DW      1Eh, errFileRead        ; Read fault
  58.         DW      20h, errAccessDenied    ; Sharing violation
  59.         DW      50h, errFileExists      ; File already exists
  60.         DW      -1, -1                  ; end marker
  61.  
  62.  
  63.  
  64. CODESEG
  65.  
  66.  
  67. ;/***************************************************************************\
  68. ;*
  69. ;* Function:     int ErrorCode(void)
  70. ;*
  71. ;* Description:  Get the MIDAS error code corresponding to DOS Extended Error.
  72. ;*
  73. ;* Returns:      MIDAS error code in ax
  74. ;*
  75. ;\***************************************************************************/
  76.  
  77. PROC    ErrorCode       _funct
  78.  
  79.         push    ds _si _di
  80.         mov     _ax,5900h               ; DOS function 59h - get extended
  81.         xor     _bx,_bx                 ; error
  82.         int     21h
  83.         pop     _di _si ds
  84.  
  85.         mov     _dx,_ax                 ; dx = extended error
  86.         xor     _bx,_bx                 ; offset to error table
  87.  
  88. @@errloop:
  89.         cmp     [errorCodes+_bx],dx     ; Is the table error code the current
  90.         je      @@errok                 ; one? If is, return the table value
  91.         cmp     [errorCodes+_bx],-1     ; end of table
  92.         je      @@noerr
  93.         add     _bx,4
  94.         jmp     @@errloop
  95.  
  96. @@errok:
  97. IFDEF __32__
  98.         xor     eax,eax
  99. ENDIF
  100.         mov     ax,[errorCodes+_bx+2]   ; ax = MIDAS error code
  101.         jmp     @@done
  102.  
  103. @@noerr:
  104.         mov     _ax,errUndefined        ; undefined error
  105.  
  106. @@done:
  107.         ret
  108. ENDP
  109.  
  110.  
  111.  
  112.  
  113.  
  114. ;/***************************************************************************\
  115. ;*
  116. ;* Function:     int rfOpen(char *fileName, int openMode, rfHandle *file);
  117. ;*
  118. ;* Description:  Opens a file for reading or writing
  119. ;*
  120. ;* Input:        char *fileName          name of file
  121. ;*               int openMode            file opening mode, see enum
  122. ;*                                       rfOpenMode
  123. ;*               rfHandle *file          pointer to file handle
  124. ;*
  125. ;* Returns:      MIDAS error code.
  126. ;*               File handle is stored in *file.
  127. ;*
  128. ;\***************************************************************************/
  129.  
  130. PROC    rfOpen          _funct  fileName : _ptr, openMode : _int, \
  131.                                 file : _ptr
  132.  
  133.         ; allocate memory for file structure:
  134.         call    memAlloc LANG, SIZE rfFile, [file]
  135.         test    _ax,_ax
  136.         jnz     @@err
  137.  
  138.         cmp     [openMode],rfOpenRead   ; open file for reading?
  139.         jne     @@noread
  140.         mov     _ax,3D00h               ; open a read only file
  141.         jmp     @@open
  142.  
  143. @@noread:
  144.         cmp     [openMode],rfOpenWrite  ; open file for writing?
  145.         jne     @@nowrite
  146.         mov     _ax,3C00h               ; create a write only file
  147.         xor     _cx,_cx
  148.         jmp     @@open
  149.  
  150. @@nowrite:
  151.         cmp     [openMode],rfOpenReadWrite      ; open for read & write?
  152.         jne     @@invmode
  153.         mov     _ax,3D02h               ; open a file for read & write
  154.         jmp     @@open
  155.  
  156. @@invmode:
  157.         mov     _ax,errInvalidArguments ; invalid function arguments
  158.         jmp     @@err
  159.  
  160. @@open:
  161.         PUSHSEGREG ds
  162.         LOADPTR ds,_dx,[fileName]       ; ds:dx = file name
  163.         int     21h
  164.         POPSEGREG ds
  165.         jc      @@doserr                ; carry set if error
  166.  
  167. IFDEF __32__
  168.         and     eax,0000FFFFh
  169. ENDIF
  170.  
  171.         LOADPTR es,_bx,[file]           ; point es:bx to handle
  172.         LOADPTR es,_bx,[_esbx]          ; point es:bx to file structure
  173.         mov     [_esbx+rfFile.handle],_ax       ; store file handle
  174.  
  175.         xor     _ax,_ax
  176.         jmp     @@done
  177.  
  178. @@doserr:
  179.         call    ErrorCode               ; get DOS error code
  180.  
  181. @@err:
  182.         ERROR   ID_rfOpen
  183.  
  184. @@done:
  185.         ret
  186. ENDP
  187.  
  188.  
  189.  
  190.  
  191.  
  192. ;/***************************************************************************\
  193. ;*
  194. ;* Function:     int rfClose(rfHandle file);
  195. ;*
  196. ;* Description:  Closes a file opened with rfOpen().
  197. ;*
  198. ;* Input:        rfHandle file           handle of an open file
  199. ;*
  200. ;* Returns:      MIDAS error code
  201. ;*
  202. ;\***************************************************************************/
  203.  
  204. PROC    rfClose         _funct  file : _ptr
  205.  
  206.         LOADPTR es,_bx,[file]           ; point es:bx to file structure
  207.         mov     _bx,[_esbx+rfFile.handle]       ; bx = file handle
  208.         mov     _ax,3E00h               ; DOS function 3Eh - close file
  209.         int     21h
  210.         jc      @@doserr                ; carry set if error
  211.  
  212.         ; deallocate file structure:
  213.         call    memFree LANG, [file]
  214.         test    _ax,_ax
  215.         jnz     @@err
  216.  
  217.         xor     _ax,_ax
  218.         jmp     @@done
  219.  
  220. @@doserr:
  221.         call    ErrorCode               ; get DOS error code
  222.  
  223. @@err:
  224.         ERROR   ID_rfClose
  225.  
  226. @@done:
  227.         ret
  228. ENDP
  229.  
  230.  
  231.  
  232.  
  233. ;/***************************************************************************\
  234. ;*
  235. ;* Function:     int rfGetSize(rfHandle file, long *fileSize);
  236. ;*
  237. ;* Description:  Get the size of a file
  238. ;*
  239. ;* Input:        rfHandle file           handle of an open file
  240. ;*               ulong *fileSize         pointer to file size
  241. ;*
  242. ;* Returns:      MIDAS error code.
  243. ;*               File size is stored in *fileSize.
  244. ;*
  245. ;\***************************************************************************/
  246.  
  247. PROC    rfGetSize       _funct  file : _ptr, fileSize : _long
  248.  
  249.         ; store current file position:
  250. IFDEF __16__
  251.         call    rfGetPosition LANG, [file], seg fpos offset fpos
  252. ELSE
  253.         call    rfGetPosition LANG, [file], ptr_to fpos
  254. ENDIF
  255.         test    _ax,_ax
  256.         jnz     @@err
  257.  
  258.         ; seek to end of file:
  259.         xor     eax,eax
  260.         call    rfSeek LANG, [file], eax, rfSeekEnd
  261.         test    _ax,_ax
  262.         jnz     @@err
  263.  
  264.  
  265.         ; read file position to *filesize:
  266.         call    rfGetPosition LANG, [file], [fileSize]
  267.         test    _ax,_ax
  268.         jnz     @@err
  269.  
  270.         ; return original file position:
  271.         call    rfSeek LANG, [file], [fpos], rfSeekAbsolute
  272.         test    _ax,_ax
  273.         jnz     @@err
  274.  
  275.         xor     _ax,_ax
  276.         jmp     @@done
  277.  
  278. @@doserr:
  279.         call    ErrorCode               ; get DOS error code
  280.  
  281. @@err:
  282.         ERROR   ID_rfGetSize
  283.  
  284. @@done:
  285.         ret
  286. ENDP
  287.  
  288.  
  289.  
  290.  
  291. ;/***************************************************************************\
  292. ;*
  293. ;* Function:     int rfRead(rfHandle file, void *buffer, ulong numBytes);
  294. ;*
  295. ;* Description:  Reads binary data from a file
  296. ;*
  297. ;* Input:        rfHandle file           file handle
  298. ;*               void *buffer            reading buffer
  299. ;*               ulong numBytes          number of bytes to read
  300. ;*
  301. ;* Returns:      MIDAS error code.
  302. ;*               Read data is stored in *buffer, which must be large enough
  303. ;*               for it.
  304. ;*
  305. ;\***************************************************************************/
  306.  
  307. PROC    rfRead          _funct  file : _ptr, buffer : _ptr, numBytes : _long
  308. LOCAL   readCount : _long, readBuf : _ptr
  309.  
  310. IFDEF __16__
  311.         mov     eax,[numBytes]          ; store number of bytes left to
  312.         mov     [readCount],eax         ; readCount
  313.         mov     eax,[buffer]            ; store buffer ptr in readBuf
  314.         mov     [readBuf],eax
  315.  
  316.         les     bx,[file]               ; point es:bx to file structure
  317.         mov     bx,[es:bx+rfFile.handle]        ; bx = file handle
  318.  
  319.         ; As the DOS read function only accepts 16 bits as number of bytes,
  320.         ; data must be read at chunks of 49152 bytes
  321.  
  322. @@readloop:
  323.         cmp     [readCount],0           ; any more bytes to read?
  324.         je      @@readok
  325.  
  326.         cmp     [readCount],49152       ; more than 49152 bytes left?
  327.         jbe     @@readrest
  328.  
  329.         ; More than 49152 bytes left to read - read 49152 bytes and advance
  330.         ; buffer pointer
  331.  
  332.         mov     ax,3F00h                ; DOS function 3Fh - read file
  333.         mov     cx,49152                ; read 49152 bytes
  334.         push    ds
  335.         lds     dx,[readBuf]            ; read to *readBuf
  336.         int     21h
  337.         pop     ds
  338.         jc      @@doserr                ; carry set if error
  339.         cmp     ax,49152                ; ax = number of bytes read. If not
  340.         jne     @@eof                   ; 49152, end of file was reached
  341.  
  342.         sub     [readCount],49152       ; 49152 bytes read
  343.         add     [word readBuf+2],3072   ; advance pointer 49152 bytes
  344.                                         ; (3072 paragraphs)
  345.         jmp     @@readloop
  346.  
  347.  
  348. @@readrest:
  349.         ; 49152 or less bytes remaining - read the rest
  350.  
  351.         mov     ax,3F00h                ; DOS function 3Fh - read file
  352.         mov     cx,[word readCount]     ; read the rest
  353.         push    ds
  354.         lds     dx,[readBuf]            ; read to *readBuf
  355.         int     21h
  356.         pop     ds
  357.         jc      @@doserr                ; carry set if error
  358.         cmp     ax,[word readCount]     ; ax = number of bytes read. If not
  359.         jne     @@eof                   ; readCount, end of file was reached
  360.  
  361.         mov     [readCount],0           ; no more to read
  362. ELSE
  363.  
  364.         mov     ebx,[file]              ; point es:bx to file structure
  365.         mov     ebx,[ebx+rfFile.handle] ; bx = file handle
  366.  
  367.         mov     eax,3F00h               ; DOS function 3Fh - read file
  368.         mov     ecx,[numBytes]
  369.         mov     edx,[buffer]
  370.         int     21h
  371.         jc      @@doserr                ; carry set if error
  372.         cmp     eax,[numBytes]          ; ax = number of bytes read. If not
  373.         jne     @@eof                   ; readCount, end of file was reached
  374.  
  375. ENDIF
  376.  
  377. @@readok:
  378.         xor     _ax,_ax
  379.         jmp     @@done
  380.  
  381. @@eof:
  382.         mov     _ax,errEndOfFile        ; unexpected end of file
  383.         jmp     @@err
  384.  
  385. @@doserr:
  386.         call    ErrorCode               ; get DOS error code
  387.         cmp     _ax,errUndefined        ; undefined error?
  388.         jne     @@err
  389. @@readerr:
  390.         mov     _ax,errFileRead         ; if is, change it to file read error
  391.  
  392. @@err:
  393.         ERROR   ID_rfRead
  394.  
  395. @@done:
  396.         ret
  397. ENDP
  398.  
  399.  
  400.  
  401.  
  402. ;/***************************************************************************\
  403. ;*
  404. ;* Function:     int rfWrite(rfHandle file, void *buffer, ulong numBytes);
  405. ;*
  406. ;* Description:  Writes binary data to a file
  407. ;*
  408. ;* Input:        rfHandle file           file handle
  409. ;*               void *buffer            pointer to data to be written
  410. ;*               ulong numBytes          number of bytes to write
  411. ;*
  412. ;* Returns:      MIDAS error code
  413. ;*
  414. ;\***************************************************************************/
  415.  
  416. PROC    rfWrite         _funct  file : _ptr, buffer : _ptr, numBytes : _long
  417. LOCAL   writeCount : _long, writeBuf : _ptr
  418.  
  419. IFDEF __16__
  420.         mov     eax,[numBytes]          ; store number of bytes left to
  421.         mov     [writeCount],eax        ; writeCount
  422.         mov     eax,[buffer]            ; store buffer ptr in writeBuf
  423.         mov     [writeBuf],eax
  424.  
  425.         les     bx,[file]               ; point es:bx to file structure
  426.         mov     bx,[es:bx+rfFile.handle]        ; bx = file handle
  427.  
  428.         ; As the DOS write function only accepts 16 bits as number of bytes,
  429.         ; data must be written at chunks of 49152 bytes
  430.  
  431. @@writeloop:
  432.         cmp     [writeCount],0          ; any more bytes to write?
  433.         je      @@writeok
  434.  
  435.         cmp     [writeCount],49152      ; more than 49152 bytes left?
  436.         jbe     @@writerest
  437.  
  438.         ; More than 49152 bytes left to write - write 49152 bytes and advance
  439.         ; buffer pointer
  440.  
  441.         mov     ax,4000h                ; DOS function 40h - write file
  442.         mov     cx,49152                ; write 49152 bytes
  443.         push    ds
  444.         lds     dx,[writeBuf]           ; write from *writeBuf
  445.         int     21h
  446.         pop     ds
  447.         jc      @@doserr                ; carry set if error
  448.         cmp     ax,49152                ; ax = number of bytes written. If
  449.         jne     @@diskfull              ; not 49152, disk is full
  450.  
  451.         sub     [writeCount],49152      ; 49152 bytes written
  452.         add     [word writeBuf+2],3072  ; advance pointer 49152 bytes
  453.                                         ; (3072 paragraphs)
  454.         jmp     @@writeloop
  455.  
  456.  
  457. @@writerest:
  458.         ; 49152 or less bytes remaining - write the rest
  459.  
  460.         mov     ax,4000h                ; DOS function 40h - read file
  461.         mov     cx,[word writeCount]    ; write the rest
  462.         push    ds
  463.         lds     dx,[writeBuf]           ; write from *readBuf
  464.         int     21h
  465.         pop     ds
  466.         jc      @@doserr                ; carry set if error
  467.         cmp     ax,[word writeCount]    ; ax = number of bytes to written. If
  468.         jne     @@diskfull              ; not writeCount, disk is full
  469.  
  470. ELSE
  471.         mov     ebx,[file]              ; point es:bx to file structure
  472.         mov     ebx,[ebx+rfFile.handle] ; bx = file handle
  473.  
  474.         mov     eax,4000h               ; DOS function 40h - read file
  475.         mov     ecx,[numBytes]
  476.         mov     edx,[buffer]
  477.         int     21h
  478.         jc      @@doserr                ; carry set if error
  479.         cmp     _ax,[numBytes]          ; ax = number of bytes to written. If
  480.         jne     @@diskfull              ; not writeCount, disk is full
  481. ENDIF
  482.  
  483. @@writeok:
  484.         xor     _ax,_ax
  485.         jmp     @@done
  486.  
  487. @@diskfull:
  488.         mov     _ax,errDiskFull         ; unexpected end of file
  489.         jmp     @@err
  490.  
  491. @@doserr:
  492.         call    ErrorCode               ; get DOS error code
  493.         cmp     _ax,errUndefined        ; undefined error?
  494.         jne     @@err
  495.         mov     _ax,errFileWrite        ; if is, change to file write error
  496.  
  497. @@err:
  498.         ERROR   ID_rfWrite
  499.  
  500. @@done:
  501.         ret
  502. ENDP
  503.  
  504.  
  505.  
  506.  
  507. ;/***************************************************************************\
  508. ;*
  509. ;* Function:     int rfSeek(rfHandle file, long newPosition, int seekMode);
  510. ;*
  511. ;* Description:  Seeks to a new position in file. Subsequent reads and writes
  512. ;*               go to the new position.
  513. ;*
  514. ;* Input:        rfHandle file           file handle
  515. ;*               long newPosition        new file position
  516. ;*               int seekMode            file seek mode, see enum rfSeekMode
  517. ;*
  518. ;* Returns:      MIDAS error code
  519. ;*
  520. ;\***************************************************************************/
  521.  
  522. PROC    rfSeek          _funct  file : _ptr, newPosition : _long, \
  523.                                 seekMode : _int
  524.  
  525. IFDEF __32__
  526.         xor     eax,eax
  527. ENDIF
  528.  
  529.         ; select DOS seek mode corresponding to seekMode:
  530.  
  531.         cmp     [seekMode],rfSeekAbsolute       ; absolute seek?
  532.         jne     @@noabs
  533.         mov     al,0
  534.         jmp     @@seek
  535.  
  536. @@noabs:
  537.         cmp     [seekMode],rfSeekRelative       ; relative seek?
  538.         jne     @@norel
  539.         mov     al,1
  540.         jmp     @@seek
  541.  
  542. @@norel:
  543.         cmp     [seekMode],rfSeekEnd            ; seek from end of file?
  544.         jne     @@invarg
  545.         mov     al,2
  546.         jmp     @@seek
  547.  
  548. @@invarg:
  549.         mov     _ax,errInvalidArguments         ; invalid seeking mode
  550.         jmp     @@err
  551.  
  552. @@seek:
  553.         LOADPTR es,_bx,[file]
  554.         mov     _bx,[_esbx++rfFile.handle]      ; bx = file handle
  555.         mov     ah,42h                  ; DOS function 42h - move file pointer
  556.         mov     cx,[word newPosition+2]
  557.         mov     dx,[word newPosition]
  558.         int     21h
  559.         jc      @@doserr
  560.  
  561.         xor     _ax,_ax
  562.         jmp     @@done
  563.  
  564. @@doserr:
  565.         call    ErrorCode               ; get DOS error code
  566.  
  567. @@err:
  568.         ERROR   ID_rfSeek
  569.  
  570. @@done:
  571.         ret
  572. ENDP
  573.  
  574.  
  575.  
  576.  
  577. ;/***************************************************************************\
  578. ;*
  579. ;* Function:     int rfGetPosition(rfHandle file, long *position);
  580. ;*
  581. ;* Description:  Reads the current position in a file
  582. ;*
  583. ;* Input:        rfHandle file           file handle
  584. ;*               long *position          pointer to file position
  585. ;*
  586. ;* Returns:      MIDAS error code.
  587. ;*               Current file position is stored in *position.
  588. ;*
  589. ;\***************************************************************************/
  590.  
  591. PROC    rfGetPosition   _funct  file : _ptr, position : _ptr
  592.  
  593.         LOADPTR es,_bx,[file]
  594.         mov     _bx,[_esbx+rfFile.handle]       ; bx = file handle
  595.  
  596.         mov     eax,4201h               ; DOS function 42h - move file pointer
  597.                                         ; 1: move relative to current position
  598.         xor     cx,cx                   ; new position = 0 (current)
  599.         xor     dx,dx
  600.         int     21h
  601.         jc      @@doserr                ; carry set if error
  602.  
  603.         ; dx:ax contains current file position - store it in *position:
  604.         LOADPTR es,_bx,[position]
  605.         les     bx,[position]
  606.         mov     [_esbx],ax
  607.         mov     [_esbx+2],dx
  608.  
  609.         xor     _ax,_ax
  610.         jmp     @@done
  611.  
  612. @@doserr:
  613.         call    ErrorCode               ; get DOS error code
  614.  
  615. @@err:
  616.         ERROR   ID_rfGetPosition
  617.  
  618. @@done:
  619.         ret
  620. ENDP
  621.  
  622.  
  623.  
  624.  
  625. ;/***************************************************************************\
  626. ;*
  627. ;* Function:     int rfFileExists(char *fileName, int *exists);
  628. ;*
  629. ;* Description:  Checks if a file exists or not
  630. ;*
  631. ;* Input:        char *fileName          file name, ASCIIZ
  632. ;*               int *exists             pointer to file exists status
  633. ;*
  634. ;* Returns:      MIDAS error code.
  635. ;*               *exists contains 1 if file exists, 0 if not.
  636. ;*
  637. ;\***************************************************************************/
  638.  
  639. PROC    rfFileExists    _funct  fileName : _ptr, exists : _ptr
  640.  
  641.         ; Attempt to open the file for reading. If this succeeds, the file
  642.         ; exists.
  643.  
  644.         PUSHSEGREG ds
  645.         LOADPTR ds,_dx,[fileName]
  646.         mov     _ax,3D00h
  647.         int     21h
  648.         POPSEGREG ds
  649.         LOADPTR es,_bx,[exists]
  650.         jc      @@nofile
  651.  
  652.         ; the file exists:
  653.         mov     [_int _esbx],1
  654.  
  655.         ; the file is still open - close it:
  656.         mov     _bx,_ax
  657.         mov     _ax,3E00h
  658.         int     21h
  659.         jmp     @@ok
  660.  
  661. @@nofile:
  662.         ; the file does not exist:
  663.         mov     [_int _esbx],0
  664.  
  665. @@ok:
  666.         xor     _ax,_ax
  667.         ret
  668.  
  669. ENDP
  670.  
  671.  
  672.  
  673. ;* $Log: asmrfile.asm,v $
  674. ;* Revision 1.2  1997/01/16 18:41:59  pekangas
  675. ;* Changed copyright messages to Housemarque
  676. ;*
  677. ;* Revision 1.1  1996/05/22 20:49:33  pekangas
  678. ;* Initial revision
  679. ;*
  680.  
  681.  
  682. END